﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace FinalPointSet.Model.Model
{
    /// <summary>
    /// 数据源映射
    /// </summary>
    public class DataSourceMapping
    {
        /// <summary>
        /// 排序
        /// </summary>
        public int Sequence { get; set; } = 0;
        /// <summary>
        /// 来源数据源
        /// </summary>
        public DataSource SourceDataSource { get; set; } = new();

        /// <summary>
        /// 映射规则
        /// </summary>
        public ObservableCollection<DataSourceMappingRule> MappingRules { get; set; } = [];
    }

    /// <summary>
    /// 数据源映射规则序列化转换器
    /// </summary>
    public class DataSourceMappingConverter : JsonConverter<DataSourceMapping>
    {
        private static readonly JsonSerializer serializer = new();
        private List<DataSource> dataSources = [];
        public DataSourceMappingConverter()
        {
            serializer.Converters.Add(new DataSourceMappingRuleConverter(dataSources));
        }
        public DataSourceMappingConverter(List<DataSource> dataSources)
        {
            // 创建一个JsonSerializer实例，并注册DataSourceMappingRuleConverter
            this.dataSources = dataSources;
            serializer.Converters.Add(new DataSourceMappingRuleConverter(dataSources));
        }
        public override void WriteJson(JsonWriter writer, DataSourceMapping? value, JsonSerializer serializer)
        {
            if (value == null) throw new ArgumentNullException(nameof(value));
            JObject obj = new()
            {
                { "Sequence", JToken.FromObject(value.Sequence) },
                // 只序列化 SourceDataSource 的 Name 属性
                { "SourceDataSource", JToken.FromObject(value.SourceDataSource.Name) }
            };
            // 序列化映射规则
            using (var stringWriter = new System.IO.StringWriter())
            {
                using var jsonWriter = new JsonTextWriter(stringWriter);
                DataSourceMappingConverter.serializer.Serialize(jsonWriter, value.MappingRules);
                string mappingRulesJson = stringWriter.ToString();
                obj.Add("MappingRules", JToken.Parse(mappingRulesJson));
            }

            // 将JObject写入JsonWriter
            obj.WriteTo(writer);
        }
        public override DataSourceMapping ReadJson(JsonReader reader, Type objectType, DataSourceMapping? existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            JObject obj = JObject.Load(reader);

            obj.TryGetValue("Sequence", out JToken? sequence);
            string strSequence = sequence?.ToString() ?? "0";
            var result = new DataSourceMapping
            {
                Sequence = int.Parse(strSequence),
                SourceDataSource = new(),
                MappingRules = [],
            };

            // 反序列化 SourceDataSource 的 Name 属性
            if (obj["SourceDataSource"] is JToken sourceDataSource)
            {
                string name = sourceDataSource.ToString();
                // 反序列化 SourceDataSource 的 Name 属性
                result.SourceDataSource.Name = name;

                if (dataSources != null && dataSources.Count > 0)
                {
                    DataSource dataSource = dataSources.FirstOrDefault(d => d.Name.Equals(name), new DataSource());
                    result.SourceDataSource.LogoPath = dataSource.LogoPath;
                    result.SourceDataSource.Sequence = dataSource.Sequence;
                }

            }

            if (obj["MappingRules"] is JArray mappingRulesArray)
            {
                // 遍历 MappingRules 数组中的每个元素
                foreach (JToken mappingRuleToken in mappingRulesArray)
                {
                    // 将每个元素转换为 JObject
                    JObject mappingRuleObject = (JObject)mappingRuleToken;

                    if (mappingRuleObject != null && dataSources != null)
                    {
                        result.MappingRules.Add(DataSourceMappingRuleConverter.Parse(mappingRuleObject, serializer, dataSources));
                    }
                }
            }
            return result;
        }

    }
}
